package com.jiangnan.warehouse_management.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.jiangnan.warehouse_management.common.exception.BusinessException;
import com.jiangnan.warehouse_management.dto.request.OutboundRecordRequest;
import com.jiangnan.warehouse_management.dto.response.OutboundRecordQueryResponse;
import com.jiangnan.warehouse_management.dto.response.OutboundRecordResponse;
import com.jiangnan.warehouse_management.mapper.OutboundRecordMapper;
import com.jiangnan.warehouse_management.mapper.ItemMapper;
import com.jiangnan.warehouse_management.mapper.UserMapper;
import com.jiangnan.warehouse_management.mapper.WarehouseMapper;
import com.jiangnan.warehouse_management.pojo.OutboundRecord;
import com.jiangnan.warehouse_management.pojo.Item;
import com.jiangnan.warehouse_management.pojo.User;
import com.jiangnan.warehouse_management.pojo.Warehouse;
import com.jiangnan.warehouse_management.service.OutboundRecordService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Timestamp;
import java.util.List;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class OutboundRecordServiceImpl implements OutboundRecordService {

    private final OutboundRecordMapper outboundRecordMapper;
    private final ItemMapper itemMapper;
    private final WarehouseMapper warehouseMapper;
    private final UserMapper userMapper;

    @Override
    public OutboundRecordQueryResponse getOutboundRecords(
            Integer page,
            Integer pageSize,
            Integer itemId,
            Integer warehouseId,
            Timestamp startTime,
            Timestamp endTime) {
        
        // 参数校验和默认值设置
        page = (page == null || page < 1) ? 1 : page;
        pageSize = (pageSize == null || pageSize < 1) ? 10 : pageSize;

        // 构建查询条件
        LambdaQueryWrapper<OutboundRecord> queryWrapper = new LambdaQueryWrapper<>();
        if (itemId != null) {
            queryWrapper.eq(OutboundRecord::getItemId, itemId);
        }
        if (warehouseId != null) {
            queryWrapper.eq(OutboundRecord::getWarehouseId, warehouseId);
        }
        if (startTime != null) {
            queryWrapper.ge(OutboundRecord::getOutboundTime, startTime);
        }
        if (endTime != null) {
            queryWrapper.le(OutboundRecord::getOutboundTime, endTime);
        }
        queryWrapper.orderByDesc(OutboundRecord::getOutboundTime);

        // 开启分页
        PageHelper.startPage(page, pageSize, true);
        
        // 执行查询
        List<OutboundRecord> records = outboundRecordMapper.selectList(queryWrapper);
        
        // 获取分页信息
        PageInfo<OutboundRecord> pageInfo = new PageInfo<>(records);

        // 转换为响应对象
        List<OutboundRecordResponse> responses = records.stream()
                .map(this::convertToResponse)
                .collect(Collectors.toList());

        // 构建返回结果
        OutboundRecordQueryResponse response = new OutboundRecordQueryResponse();
        response.setList(responses);
        response.setTotal(pageInfo.getTotal());
        response.setPage(page);
        response.setPageSize(pageSize);

        return response;
    }

    @Override
    @Transactional
    public OutboundRecord createOutboundRecord(OutboundRecordRequest request) {
        // 检查物品是否存在
        Item item = itemMapper.selectById(request.getItemId());
        if (item == null) {
            throw new BusinessException(404, "物品不存在");
        }

        // 检查仓库是否存在
        Warehouse warehouse = warehouseMapper.selectById(request.getWarehouseId());
        if (warehouse == null) {
            throw new BusinessException(404, "仓库不存在");
        }

        // 创建出库记录
        OutboundRecord record = new OutboundRecord();
        BeanUtils.copyProperties(request, record);

        // 设置出库时间
        record.setOutboundTime(new Timestamp(System.currentTimeMillis()));

        // TODO: 从当前登录用户中获取操作员ID
        // 这里暂时使用固定值1，实际应该从SecurityContext中获取当前登录用户
        record.setOperatorId(1);

        // 保存出库记录
        int rows = outboundRecordMapper.insert(record);
        if (rows != 1) {
            throw new BusinessException(500, "创建出库记录失败");
        }

        // 重新查询记录以获取自动计算的totalAmount
        return outboundRecordMapper.selectById(record.getOutboundId());
    }

    @Override
    public OutboundRecordResponse getOutboundRecordById(Integer id) {
        // 参数校验
        if (id == null) {
            throw new BusinessException(400, "出库记录ID不能为空");
        }

        // 查询出库记录
        OutboundRecord record = outboundRecordMapper.selectById(id);
        if (record == null) {
            throw new BusinessException(404, "出库记录不存在");
        }

        // 转换为响应对象
        return convertToResponse(record);
    }

    private OutboundRecordResponse convertToResponse(OutboundRecord record) {
        OutboundRecordResponse response = new OutboundRecordResponse();
        BeanUtils.copyProperties(record, response);

        // 设置物品信息
        Item item = itemMapper.selectById(record.getItemId());
        if (item != null) {
            OutboundRecordResponse.ItemDTO itemDTO = new OutboundRecordResponse.ItemDTO();
            itemDTO.setItemId(item.getItemId());
            itemDTO.setItemName(item.getItemName());
            response.setItem(itemDTO);
        }

        // 设置仓库信息
        Warehouse warehouse = warehouseMapper.selectById(record.getWarehouseId());
        if (warehouse != null) {
            OutboundRecordResponse.WarehouseDTO warehouseDTO = new OutboundRecordResponse.WarehouseDTO();
            warehouseDTO.setWarehouseId(warehouse.getWarehouseId());
            warehouseDTO.setWarehouseName(warehouse.getWarehouseName());
            response.setWarehouse(warehouseDTO);
        }

        // 设置操作员信息
        User operator = userMapper.selectById(record.getOperatorId());
        if (operator != null) {
            OutboundRecordResponse.OperatorDTO operatorDTO = new OutboundRecordResponse.OperatorDTO();
            operatorDTO.setUserId(operator.getUserId());
            operatorDTO.setUsername(operator.getUsername());
            operatorDTO.setRealName(operator.getRealName());
            response.setOperator(operatorDTO);
        }

        return response;
    }
} 